package com.bradz.mytv;

import java.util.TimerTask;

import org.json.JSONException;
import org.json.JSONObject;

import com.android.vending.billing.IInAppBillingService;
import com.bradz.mytv.activityMain.Constants;
import com.bradz.mytv.activityMain.LoadBillingTask;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.IntentSender.SendIntentException;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class activityHelp extends Activity {
	TextView help_box;
	private ImageView verify_network;
	private classNetworkHolder network;
	private applicationGlobalVars globals;
	private Context self;
	
	private IInAppBillingService mService;
	private ServiceConnection mServiceConn;
	private classAndroidLogger logger;
	Bundle buyIntentBundle;
	
	Handler myHandler = new Handler() {

  	    @Override
  	    public void handleMessage(Message msg) {
  	        switch (msg.what) {
	  	        case 0:
	  	        	sent_donation_purchase();
	  	            break;
	  	        default:
	  	            break;
  	        }
  	    }
  	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_help);
		logger = new classAndroidLogger("ActivityMain");
		globals = ((applicationGlobalVars) this.getApplication());
		help_box = (TextView) findViewById(R.id.help_text);
		Typeface font_normal = Typeface.createFromAsset(getAssets(),"fonts/Neutraface2Text-Demi.otf");
		TextView title = (TextView) findViewById(R.id.manage_channels_title);
		title.setTypeface(font_normal);
		self = this;
		final classInfoPopUp info_popup = new classInfoPopUp(self,this.getBaseContext(),getAssets(),myHandler);
		//Sends in the image and the display so that the actions can be attached and the popup can be placed correctly
		info_popup.attach_popup_window((ImageView)findViewById(R.id.info_button),getWindowManager().getDefaultDisplay());
		new initialize_network_task().execute(false);
		bind_billing_activities();
		initialize_buttons();
	}
	
	@Override
    public void onResume(){
    	super.onResume();
    	//This needs to be here so that the network is updated whenever
    	//an activity returns to this activity.
    	new initialize_network_task().execute(false);
    	initialize_buttons();
    }
	
	public void initialize_buttons(){
		help_box.setMovementMethod(new ScrollingMovementMethod());
		final classStaticText help_text = new classStaticText();
		help_box.setText(help_text.purpose);
		Typeface font_book = Typeface.createFromAsset(getAssets(),"fonts/Neutraface2Text-Book.otf");
		help_box.setTypeface(font_book);
		init_help_buttons((Button) findViewById(R.id.help_navigation_purpose),help_text.purpose);
		init_help_buttons((Button) findViewById(R.id.help_navigation_started),help_text.getting_started);
		init_help_buttons((Button) findViewById(R.id.help_navigation_mediaplayer),help_text.media_player);
		init_help_buttons((Button) findViewById(R.id.help_navigation_channel),help_text.channel_settings);
		init_help_buttons((Button) findViewById(R.id.help_navigation_network),help_text.network_settings);
		init_help_buttons((Button) findViewById(R.id.help_faq),help_text.faq);
		//init_help_buttons((Button) findViewById(R.id.help_about),help_text.about);
	}
	public void init_help_buttons(Button button, final String help_text){
		Typeface font_italic = Typeface.createFromAsset(getAssets(),"fonts/Neutraface2Text-DemiItalic.otf");
		button.setTypeface(font_italic);
		button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	help_box.setText(help_text);
            	help_box.setMovementMethod(new ScrollingMovementMethod());
            }
        });
	}
	//This loads the global network into the current activity
	private class initialize_network_task extends AsyncTask<Boolean, Void, Void> {

			@Override
	        protected void onPreExecute() {
				verify_network = (ImageView)findViewById(R.id.network_indicator);
			}
			
			@Override
			protected Void doInBackground(Boolean... update_network) {
				if(!update_network[0]){
					Log.i("activityHelp - Thread","Pulling Network...");
					//This waits for the global network to be created
					if(!globals.get_network_loaded()){
						network = new classNetworkHolder(self);
			            while (network.not_initialized) {}
						globals.set_network_object(network);
						globals.set_network_loaded(true);
					}else{
						network = globals.get_network_object();
					}
				}else{
					Log.i("activityHelp - Thread","Saving Network...");
					//Resaves the global network when the activity is resumed. This assumes that the network
					//has been changed in the config in some way. Thrown together mutex lock
					globals.set_network_loaded(false);
					network = new classNetworkHolder(self);
		            while (network.not_initialized) {}
		            globals.set_network_object(network);
		            globals.set_network_loaded(true);
		            //network.reset_recovery_database();
				}
				return null;
			}
			
			@Override
		    protected void onPostExecute(Void v) {
	            if(!network.network_empty()){
					verify_network.setImageDrawable(getResources().getDrawable(R.drawable.object_circle_green));
				}
		    }
		}
	public void bind_billing_activities(){
		mServiceConn = new ServiceConnection() {
			   @Override
			   public void onServiceDisconnected(ComponentName name) {
				   logger.info("Billing Service Disconnected...");
				   mService = null;
			   }

			   @Override
			   public void onServiceConnected(ComponentName name, IBinder service) {
				   logger.info("Billing Service Connected...");
				   mService = IInAppBillingService.Stub.asInterface(service);
			   }
		};
		bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);
	}
	
	public void sent_donation_purchase(){
		classDeveloperPayload payload = new classDeveloperPayload();
    	
    	LoadBillingTask task = new LoadBillingTask(payload.get_payload(), "mytv_donation");
    	
    	task.run();
	}
	
    class LoadBillingTask extends TimerTask {
        private Handler mHandler = new Handler(Looper.getMainLooper());
		String payload;
		String item_name;

        LoadBillingTask(String payload, String item_name){
        	logger.info("Init Billing");
  			this.payload = payload;
  			this.item_name = item_name;
  			logger.info("Done Init Billing");
        }
        
        @Override
        public void run() {
           mHandler.post(new Runnable() {
              public void run() {
            	  try {
            		  logger.info("Starting runnable");
            		  logger.info("package: " + getPackageName());
            		  logger.info("item: " + item_name);
            		  logger.info("payload: " + payload);
            		if(mService == null){
            			logger.info("mService: invalid");
            			logger.toast("There was a problem connecting to the billing service", self);
            		}else{
            			logger.info("mService: valid");
            			buyIntentBundle = mService.getBuyIntent(3, getPackageName(), item_name, "inapp", payload);
            			logger.info("Intent info");
            			if(buyIntentBundle.getInt("RESPONSE_CODE") != 7){
	            			logger.info("Starting pending intent");
	            			
	          				PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
	          				
	          				logger.info("Starting sender for result");
	          				startIntentSenderForResult(pendingIntent.getIntentSender(),
	          					   1641, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
	          					   Integer.valueOf(0));
            			}else{
            				logger.toast("This product has already been purchased!", self);
            			}
            		}
      			} catch (RemoteException e) {
      				logger.error(e.toString());
      				e.printStackTrace();
      			} catch (SendIntentException e) {
      				logger.error(e.toString());
      				e.printStackTrace();
      			} catch (Exception e){
      				logger.error(e.toString());
      				e.printStackTrace();
      			}
              }
           });
         }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)    
    {
        super.onActivityResult(requestCode, resultCode, data);
        logger.info("RequestCode: " + requestCode);
        logger.info("ResultCode: " + resultCode);
        if (requestCode == 1641 && resultCode == Activity.RESULT_OK) {           
        	logger.info("onactivity result called inside request code");
            try{
            	
            	logger.info("Parsing response data");
	            int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
	            logger.info("ResponseCode: " + responseCode);
	            String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
	            logger.info("purchaseData: " + purchaseData);
	            String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
	            logger.info("dataSignature: " + dataSignature);
	            
	            
	            if (responseCode == Constants.BILLING_RESPONSE_RESULT_OK) {
	                try {
    	                JSONObject jo = new JSONObject(purchaseData);
    	                String sku = jo.getString("productId");
    	                logger.info("productId: " + sku);
    	                //This is where the purchase needs to actually be put into the system...
    	                
    	                JSONObject o = new JSONObject(purchaseData);
    	                logger.info("Purchase Data: " + o.toString());
    	                String mOrderId = o.optString("orderId");
    	                logger.info("mOrderId: " + mOrderId);
    	                String mPackageName = o.optString("packageName");
    	                logger.info("mPackageName: " + mPackageName);
    	                String mSku = o.optString("productId");
    	                logger.info("mSku: " + mSku);
    	                long mPurchaseTime = o.optLong("purchaseTime");
    	                logger.info("purchaseTime: " + mPurchaseTime);
    	                int mPurchaseState = o.optInt("purchaseState");
    	                logger.info("mPurchaseState: " + mPurchaseState);
    	                String mDeveloperPayload = o.optString("developerPayload");
    	                logger.info("mDeveloperPayload: " + mDeveloperPayload);
    	                String mToken = o.optString("token", o.optString("purchaseToken"));
    	                logger.info("mToken: " + mToken);
    	                
    	                //Need to consume the purchase before returning
    	                try {
    	                    mService.consumePurchase(3, getPackageName(), mToken);
    	                } catch (RemoteException e) {
    	                	logger.error(e.toString());
    	                    e.printStackTrace();
    	                }
    	                
    	                //This is the method that reflects back to the prototype
                		Object[] parameterTypes = new Object[2];
                        parameterTypes[0] = Integer.valueOf(o.optString("developerPayload").split(">>>")[0]);
                        parameterTypes[1] = mToken;
                		
    					try {
	    	                logger.toast("Thank you for your donation! Now we can afford to eat tonight!", self);
    						
    					} catch (IllegalArgumentException e) {
    						// TODO Auto-generated catch block
    						logger.error(e.toString());
    						e.printStackTrace();
    					} 
	                }catch (JSONException e) {
	                            Toast.makeText(this, "Failed to parse purchase data.", Toast.LENGTH_SHORT);
	                            logger.error(e.toString());
	                            e.printStackTrace();
	                }
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_USER_CANCELED) {
	                	logger.error("User cancelled purchase"); 
	                	Toast.makeText(this, "User cancelled purchase.", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE) {
	                	logger.error("Your Device doesn't support inapp billing"); 
	                	Toast.makeText(this, "Your Device doesn't support inapp billing.", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE) {
	                	logger.error("Item is not available for billing"); 
	                	Toast.makeText(this, "Item is not available for billing", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_DEVELOPER_ERROR) {
	                	logger.error("Can't purchase item due to some developer error"); 
	                	Toast.makeText(this, "Can't purchase item due to some developer error.", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_ERROR) {
	                	logger.error("Can't purchase item due to some error in response"); 
	                	Toast.makeText(this, "Can't purchase item due to some error in response.", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED) {
	                	logger.error("You already own this item"); 
	                	Toast.makeText(this, "You already own this item.", Toast.LENGTH_SHORT).show();
	                }else if (responseCode == Constants.BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED) {
	                	logger.error("You don't own this item");
	                    Toast.makeText(this, "You don't own this item.", Toast.LENGTH_SHORT).show();
	                }
            }catch(Exception e){
            	logger.error(e.toString());
            	logger.error("Unable to make purchase");
            	Toast.makeText(this, "Unable to make purchase.", Toast.LENGTH_SHORT).show();
            }
        }
        
    }
    
    public class Constants{
    	static final int BILLING_RESPONSE_RESULT_OK	= 0;
    	static final int BILLING_RESPONSE_RESULT_USER_CANCELED = 1;
    	static final int BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE = 3;
    	static final int BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE	= 4;
    	static final int BILLING_RESPONSE_RESULT_DEVELOPER_ERROR = 5;
    	static final int BILLING_RESPONSE_RESULT_ERROR = 6;
    	static final int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;
    	static final int BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED = 8;
    }
}